local io = require[[async-io]]
local async = require[[async]].new()
local stream = require[[stream]]

local is = function(x) return function(y) return y == x end end
local gt = function(x) return function(y) return y >  x end end
local always = function(x) return function() return x end end
local plus = function() return function(a, b) return a + b end end
local take_last = function() return function(x) return x[#x] end end
local count = function() return function(x) return #x end end

io.install(async, stream)
local button = stream.from_button_press()
local btn_a = button:filter(is('a')):map(always(1))
local btn_d = button:filter(is('d')):map(always(-1))
local pos = btn_a:merge(btn_d):scan(plus(), 0)
pos.on_event(function(t, x) print(t, x) end)

local btn_d_count = button:filter(is('q')):throttle(0.3):map(count())
local d_single = btn_d_count:filter(is(1)):map(always("double hit q to exit"))
local d_double = btn_d_count:filter(is(2)).on_event(function() async:quit() end)
local d_more = btn_d_count:filter(gt(2)):map(function(x) return ("awesome %d hit"):format(x) end)
local d_text = d_single:merge(d_more)
d_text.on_event(function(t, x) print(t, x) end)

async:run()

